﻿using Abp.Domain.Repositories;
using Choucius.Boilerplate9.PlasticContainerLogs;
using Choucius.Boilerplate9.PlasticContainers;
using Choucius.Boilerplate9.RubberFrames;
using Choucius.Boilerplate9.RubberFrameLogs;
using Choucius.Boilerplate9.InboundPlasticContainerLogs;
using Choucius.Boilerplate9.InboundRubberFrameLogs;
using Choucius.Boilerplate9.OutboundPlasticContainerLogs;
using Choucius.Boilerplate9.OutboundRubberFrameLogs;
using Choucius.Boilerplate9.DtoBase;
using Choucius.Boilerplate9.Common;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Choucius.Boilerplate9.Enum;
using System.Text;

namespace Choucius.Boilerplate9.UR6258
{
    /// <summary>
    /// UR6258安卓屏RFID读写门
    /// </summary>
    public class UR6258AppService : IUR6258AppService
    {
        private readonly IRepository<PlasticContainer, Guid> _plasticContainerRepository;
        private readonly IRepository<PlasticContainerLog, long> _plasticContainerLogRepository;
        private readonly IRepository<InboundPlasticContainerLog, long> _inboundPlasticContainerLogRepository;
        private readonly IRepository<OutboundPlasticContainerLog, long> _outboundPlasticContainerLogRepository;
        private readonly IRepository<RubberFrame, Guid> _rubberFrameRepository;
        private readonly IRepository<RubberFrameLog, long> _rubberFrameLogRepository;
        private readonly IRepository<InboundRubberFrameLog, long> _inboundRubberFrameLogRepository;
        private readonly IRepository<OutboundRubberFrameLog, long> _outboundRubberFrameLogRepository;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="plasticContainerRepository"></param>
        /// <param name="plasticContainerLogRepository"></param>
        /// <param name="inboundPlasticContainerLogRepository"></param>
        /// <param name="outboundPlasticContainerLogRepository"></param>
        /// <param name="rubberFrameRepository"></param>
        /// <param name="rubberFrameLogRepository"></param>
        /// <param name="inboundRubberFrameLogRepository"></param>
        /// <param name="outboundRubberFrameLogRepository"></param>
        public UR6258AppService(IRepository<PlasticContainer, Guid> plasticContainerRepository, IRepository<PlasticContainerLog, long> plasticContainerLogRepository, IRepository<InboundPlasticContainerLog, long> inboundPlasticContainerLogRepository, IRepository<OutboundPlasticContainerLog, long> outboundPlasticContainerLogRepository, IRepository<RubberFrame, Guid> rubberFrameRepository, IRepository<RubberFrameLog, long> rubberFrameLogRepository, IRepository<InboundRubberFrameLog, long> inboundRubberFrameLogRepository, IRepository<OutboundRubberFrameLog, long> outboundRubberFrameLogRepository)
        {
            _plasticContainerRepository = plasticContainerRepository;
            _plasticContainerLogRepository = plasticContainerLogRepository;
            _inboundPlasticContainerLogRepository = inboundPlasticContainerLogRepository;
            _outboundPlasticContainerLogRepository = outboundPlasticContainerLogRepository;
            _rubberFrameRepository = rubberFrameRepository;
            _rubberFrameLogRepository = rubberFrameLogRepository;
            _inboundRubberFrameLogRepository = inboundRubberFrameLogRepository;
            _outboundRubberFrameLogRepository = outboundRubberFrameLogRepository;
        }

        #region 废弃的功能
        /*  
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        //[HttpPost]
        public async Task BulkInsertItems(ImportDto dto)
        {
            if (dto.PlasticContainers != null &&  dto.PlasticContainers.Any())
            {
                foreach (var item in dto.PlasticContainers)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var newItem = new PlasticContainer
                    {
                        RFID = rfid,
                        Status = item.Status,
                        CreationTime = DateTime.Now,
                        CreatorUserId = item.CreatorUserId
                    };
                    await _plasticContainerRepository.InsertAsync(newItem);

                    var newLog = new PlasticContainerLog
                    {
                        RFID = rfid,
                        Status = item.Status,
                        CreationTime = DateTime.Now,
                        CreatorUserId = item.CreatorUserId
                    };
                    await _plasticContainerLogRepository.InsertAsync(newLog);
                }
            }
            if (dto.RubberFrames != null && dto.RubberFrames.Any())
            {
                foreach (var item in dto.RubberFrames)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var newItem = new RubberFrame
                    {
                        RFID = rfid,
                        Status = item.Status,
                        CreationTime = DateTime.Now,
                        CreatorUserId = item.CreatorUserId
                    };
                    await _rubberFrameRepository.InsertAsync(newItem);

                    var newLog = new RubberFrameLog
                    {
                        RFID = rfid,
                        Status = item.Status,
                        CreationTime = DateTime.Now,
                        CreatorUserId = item.CreatorUserId
                    };
                    await _rubberFrameLogRepository.InsertAsync(newLog);
                }
            }
            //await _repository.SaveChangesAsync();
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        //[HttpPost]
        public async Task BulkUpdateItems(ImportDto dto)
        {
            if (dto.PlasticContainers != null && dto.PlasticContainers.Any())
            {
                foreach (var item in dto.PlasticContainers)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var entity = _plasticContainerRepository.GetAllList().FirstOrDefault(x => x.RFID == rfid);
                    if (entity != null)
                    {
                        entity.Status = item.Status;
                        entity.LastModificationTime = DateTime.Now;
                        entity.LastModifierUserId = item.LastModifierUserId;
                        _plasticContainerRepository.Update(entity);

                        // 历史记录
                        var newLog = new PlasticContainerLog
                        {
                            RFID = rfid,
                            Status = item.Status,
                            CreationTime = DateTime.Now,
                            CreatorUserId = item.CreatorUserId
                        };
                        await _plasticContainerLogRepository.InsertAsync(newLog);
                    }
                }
            }
            if (dto.RubberFrames != null && dto.RubberFrames.Any())
            {
                foreach (var item in dto.RubberFrames)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var entity = _rubberFrameRepository.GetAllList().FirstOrDefault(x => x.RFID == rfid);
                    if (entity != null)
                    {
                        entity.Status = item.Status;
                        entity.LastModificationTime = DateTime.Now;
                        entity.LastModifierUserId = item.LastModifierUserId;
                        _rubberFrameRepository.Update(entity);

                        // 历史记录
                        var newLog = new RubberFrameLog
                        {
                            RFID = rfid,
                            Status = item.Status,
                            CreationTime = DateTime.Now,
                            CreatorUserId = item.CreatorUserId
                        };
                        await _rubberFrameLogRepository.InsertAsync(newLog);
                    }
                }
            }
        }
        */
        #endregion

        /// <summary>
        /// 接收批量过门RFID标签数据并保存
        /// </summary>
        /// <param name="importDto"></param>
        /// <returns></returns>
        public async Task<ResponseDto> ReceiveBulkDataAndSave(ImportDto importDto)
        {
            var response = new ResponseDto()
            { 
                Code = 1,
                Message = "成功。"
            };
            int deviceId = importDto.DeviceId;
            if (deviceId == 2)  // 2#门：入库
            {
                _ = Device02ExecuteAsync(importDto);
            }
            if (deviceId == 3)  // 3#门：出库
            {
                _ = Device03ExecuteAsync(importDto);
            }
            if (deviceId == 4)  // 4#门：只检测是否存在未涂油的产品，不做数据库写入操作
            {
                var sb = new StringBuilder();
                foreach (var item in importDto.PlasticContainers)
                {
                    string rfid = item.RFID.Length <= 16 ? item.RFID : item.RFID.Substring(0, 16);
                    var entity = _plasticContainerRepository.FirstOrDefault(x => x.RFID == rfid);
                    if (entity == null)
                    {
                        continue;
                    }
                    if (entity.NeedInunction && entity.Status != LabelStatus.OilCoated)
                    {
                        sb.Append(rfid + "，");
                    }
                }
                if (sb.Length > 0)
                {
                    response.Code = 4;
                    response.Message = $"未涂油：{sb}需返回。";
                }
                return response;
            }
            _ = BulkUpdatePlasticContainersAsync(importDto.PlasticContainers, deviceId);
            _ = BulkUpdatePlasticContainersAsync(importDto.RubberFrames, deviceId);
            return response;
        }

        private void Device01Execute()
        {
            // TODO: 清空所有过门的RFID中的产品信息（EPC区17~24位置FFFFFFFF）
        }

        /// <summary>
        /// #2号门，入包材库
        /// </summary>
        /// <param name="importDto">入库包材RFID集合</param>
        private async Task Device02ExecuteAsync(ImportDto importDto)
        {
            if (importDto.PlasticContainers != null && importDto.PlasticContainers.Count != 0)
            {
                var inboundPlasticContainerLog = new InboundPlasticContainerLog
                {
                    DeviceId = 2,
                    LabelCount = importDto.PlasticContainers.Count,
                    CreationTime = DateTime.Now,
                    CreatorUserId = 1
                };
                await _inboundPlasticContainerLogRepository.InsertAsync(inboundPlasticContainerLog);
            }
            if (importDto.RubberFrames != null && importDto.RubberFrames.Any())
            {
                var inboundRubberFrameLog = new InboundRubberFrameLog
                {
                    DeviceId = 2,
                    LabelCount = importDto.RubberFrames.Count,
                    CreationTime = DateTime.Now,
                    CreatorUserId = 1
                };
                await _inboundRubberFrameLogRepository.InsertAsync(inboundRubberFrameLog);
            }
        }

        /// <summary>
        /// #3号门，出包材库
        /// </summary>
        /// <param name="importDto">出库包材RFID集合</param>
        private async Task Device03ExecuteAsync(ImportDto importDto)
        {
            if (importDto.PlasticContainers != null && importDto.PlasticContainers.Any())
            {
                var outboundPlasticContainerLog = new OutboundPlasticContainerLog
                {
                    DeviceId = 3,
                    LabelCount = importDto.PlasticContainers.Count,
                    CreationTime = DateTime.Now,
                    CreatorUserId = 1
                };
                await _outboundPlasticContainerLogRepository.InsertAsync(outboundPlasticContainerLog);
            }
            if (importDto.RubberFrames != null && importDto.RubberFrames.Any())
            {
                var outboundRubberFrameLog = new OutboundRubberFrameLog
                {
                    DeviceId = 3,
                    LabelCount = importDto.RubberFrames.Count,
                    CreationTime = DateTime.Now,
                    CreatorUserId = 1
                };
                await _outboundRubberFrameLogRepository.InsertAsync(outboundRubberFrameLog);
            }
        }

        private async Task BulkUpdatePlasticContainersAsync(List<PlasticContainer> plasticContainers, int deviceId)
        {
            if (plasticContainers != null && plasticContainers.Count != 0)
            {
                foreach (var item in plasticContainers)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var entity = _plasticContainerRepository.GetAllList().FirstOrDefault(x => x.RFID == rfid);
                    if (entity != null)
                    {
                        entity.Status = item.Status;
                        entity.LastModificationTime = DateTime.Now;
                        entity.LastModifierUserId = item.LastModifierUserId;
                        if (deviceId == 1)
                        {
                            entity.EPC = rfid + "FFFFFFFF";
                        }
                        _plasticContainerRepository.Update(entity);
                        // 历史记录
                        var plasticContainerLog = new PlasticContainerLog
                        {
                            DeviceId = deviceId,
                            RFID = rfid,
                            Status = item.Status,
                            CreationTime = DateTime.Now,
                            CreatorUserId = item.CreatorUserId
                        };
                        await _plasticContainerLogRepository.InsertAsync(plasticContainerLog);
                    }
                    else
                    {
                        // TODO: 对未知RFID标签处理
                    }
                }
            }
        }

        private async Task BulkUpdatePlasticContainersAsync(List<RubberFrame> rubberFrames, int deviceId)
        {
            if (rubberFrames != null && rubberFrames.Count != 0)
            {
                foreach (var item in rubberFrames)
                {
                    string rfid = RFID.GetRFIDfromEPC(item.RFID);
                    var entity = _rubberFrameRepository.GetAllList().FirstOrDefault(x => x.RFID == rfid);
                    if (entity != null)
                    {
                        entity.Status = item.Status;
                        entity.LastModificationTime = DateTime.Now;
                        entity.LastModifierUserId = item.LastModifierUserId;
                        if (deviceId == 1)
                        {
                            entity.EPC = rfid + "FFFFFFFF";
                        }
                        _rubberFrameRepository.Update(entity);

                        // 历史记录
                        var rubberFrameLog = new RubberFrameLog
                        {
                            DeviceId = deviceId,
                            RFID = rfid,
                            Status = item.Status,
                            CreationTime = DateTime.Now,
                            CreatorUserId = item.CreatorUserId
                        };
                        await _rubberFrameLogRepository.InsertAsync(rubberFrameLog);
                    }
                    else
                    {
                        // TODO: 对未知RFID标签处理
                    }
                }
            }
        }
    }
}
